
//打包
module DataBuilder {
	var dataBuffer: ArrayBuffer = null;
	var dataView: DataView = null;
	var offset = 0;
	//外部访问此方法
	export function WSSendMsg(msgId: any, data: any) {
		if (Global.isEmpty(msgId) || Global.isEmpty(data)) {
			return
		}
		let byte: egret.ByteArray = new egret.ByteArray();
		let MinID: number = msgId.wMainCmdID
		let SubID: number = msgId.wSubCmdID
		let PacketLenght: number = msgId.nLenght
		let Data = msgId.data;

		dataBuffer = new ArrayBuffer(PacketLenght);
		dataView = new DataView(dataBuffer);
		offset = 0;
		for (let i = 0; i < Data.length; i++) {
			let arg = data[Data[i][0]]
			if (arg != null) {
				let buildData = [].concat(Data[i])
				let lastdata = ""
				if (buildData.length > 2) {
					lastdata = buildData.pop()
					buildData.push(arg)
					buildData.push(lastdata)
				} else {
					buildData.push(arg)
				}
				build([buildData])
			}
		}

		let PacketBoy_ = new Uint8Array(dataBuffer)
		let AllPacketLenght = PacketBoy_.length + 8
		dataBuffer = new ArrayBuffer(AllPacketLenght);
		dataView = new DataView(dataBuffer);
		offset = 0;

		build([
			["cbVersion", "BYTE", 1],
			["cbCheckCode", "BYTE", 0],
			["wPacketSize", "WORD", PacketLenght],
			["wMainCmdID", "WORD", MinID],
			["wSubCmdID", "WORD", SubID]]);
		let AllPacket_ = new Uint8Array(dataBuffer);
		let SendAllPacket = new Uint8Array(AllPacketLenght);
		for (var i = 0; i < AllPacket_.length; i++) {
			SendAllPacket[i] = AllPacket_[i];
		}
		for (var _i = 0; _i < PacketBoy_.length; _i++) { //
			SendAllPacket[_i + 8] = PacketBoy_[_i]; //
		}
		byte._writeUint8Array(SendAllPacket);
		byte.position = 0;
		return byte
	}

	function isLittleEndian() {
		var buffer = new ArrayBuffer(2);
		new DataView(buffer).setInt16(0, 256, true);
		return new Int16Array(buffer)[0] === 256;
	}
	function writeDWord(value) {
		var _vInt = parseInt(value);
		dataView.setInt8(offset++, _vInt % (0xff + 1));
		dataView.setInt8(offset++, (_vInt % (0xffff + 1)) / (0xff + 1));
		dataView.setInt8(offset++, (_vInt % (0xffffff + 1)) / (0xffff + 1));
		dataView.setInt8(offset++, _vInt / (0xffffff + 1));
	}
	function writeInt(value) {
		dataView.setInt32(offset, value, isLittleEndian());
		offset += 4;
	}
	function writeWord(value) {
		var _vInt = parseInt(value);
		dataView.setInt8(offset++, _vInt % (0xff + 1));
		dataView.setInt8(offset++, _vInt / (0xff + 1));
	}
	function writeDLONG(value) {
		var _vInt = parseInt(value);
		dataView.setInt8(offset++, _vInt % (0xFF + 1));
		dataView.setInt8(offset++, _vInt % (0xFFFF + 1) / (0xFF + 1));
		dataView.setInt8(offset++, _vInt % (0xFFFFFF + 1) / (0xFFFF + 1));
		dataView.setInt8(offset++, _vInt % (0xFFFFFFFF + 1) / (0xFFFFFF + 1));
		dataView.setInt8(offset++, _vInt % (0xFFFFFFFFFF + 1) / (0xFFFFFFFF + 1));
		dataView.setInt8(offset++, _vInt % (0xFFFFFFFFFFFF + 1) / (0xFFFFFFFFFF + 1));
		dataView.setInt8(offset++, _vInt % (0xFFFFFFFFFFFFFF + 1) / (0xFFFFFFFFFFFF + 1));
		dataView.setInt8(offset++, _vInt / (0xFFFFFFFFFFFFFFFF + 1));
	}
	function writeFloat(value) {
		var _vInt = parseInt(value);
		dataView.setFloat32(offset, _vInt, isLittleEndian());
		offset += 4;
	}
	function writeDouble(value) {
		dataView.setFloat64(offset, value, isLittleEndian());
		offset += 8;
	}
	function writeByte(value) {
		dataView.setUint8(offset, value);
		offset += 1;
	}
	function writeBoolean(value) {
		var bByte = 0;
		if (value) {
			bByte = 1;
		}

		dataView.setUint8(offset, bByte);
		offset += 1;
	}
	function writeByteArray(value, len) {
		for (var i = 0; i < len; i++) {
			dataView.setUint8(offset, value[i]);
			offset += 1;
		}
	}
	function writeTChar(value) {
		dataView.setUint16(offset, value.charCodeAt(0), isLittleEndian());
		offset += 2;
	}
	function writeTCharArray(value, len) {
		for (var i = 0; i < len; i++) {
			if (i < value.length) {
				let leng = value.length
				let a = value.charCodeAt(i)
				dataView.setUint16(offset, value.charCodeAt(i), isLittleEndian());
				offset += 2;
			} else {
				dataView.setUint16(offset, 0, isLittleEndian());
				offset += 2;
				break;
			}

		}
	}
	function writeChineseArray(value, len) {
		let offse = offset
		for (var i = 0; i < len; i++) {
			if (i < value.length) {
				let leng = value.length
				let b: number = value[i]
				let code = value[i].charCodeAt(0)
				if (code > 127) {
					var myUrl: Url = new Url();
					let bstring = b.toString()
					var tovalue: number = myUrl.encode(bstring);
					dataView.setUint16(offse, tovalue, isLittleEndian());
					offse += 2;
				} else {
					dataView.setUint8(offse, code);
					offse += 1;
				}

			} else {
				dataView.setUint16(offse, 0, isLittleEndian());
				offset += len;
				break;
			}

		}
	}
	function windy_writeTCharArray(value, len) {
		for (var i = 0; i < len; i++) {
			if (i < value.length) {
				let leng = value.length
				dataView.setUint16(offset, value.charCodeAt(i), isLittleEndian());
				offset += 1;
			} else {
				dataView.setUint16(offset, 0, isLittleEndian());
				offset += 1;
				break;
			}

		}
	}
	function writeChar(value) {
		dataView.setUint8(offset, value.charCodeAt(0));
		offset += 1;
	}
	function writeCharArray(value, len) {
		for (var i = 0; i < len; i++) {
			if (i < value.length) {
				var _vCode = value.charCodeAt(i);
				dataView.setUint8(offset++, _vCode % 0xff);
				dataView.setUint8(offset++, _vCode / 0xff);
			} else {
				dataView.setUint8(offset++, 0x0);
				dataView.setUint8(offset++, 0x0);
			}

		}
	}
	function writeInt64Number(value) {

		var dWord1 = Math.floor(value / Math.pow(2, 32)) >>> 0;
		var dWord2 = (value % Math.pow(2, 32)) >>> 0;


		if (isLittleEndian()) {
			writeDWord(dWord2);
			writeDWord(dWord1);
		} else {
			writeDWord(dWord1);
			writeDWord(dWord2);
		}
	}
	//writeInt64Buffer([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
	function writeInt64Buffer(value) {
		var i;
		if (isLittleEndian()) {
			for (i = 7; i < 0; i--) {
				writeByte(value[i]);
			}
		} else {
			for (i = 0; i < 8; i++) {
				writeByte(value[i]);
			}
		}
	}
	//根据格式写入
	//	[
	//	 [描述,类型,值],
	//	 [描述,类型,值],
	//	[描述, "STRUCT", [[描述,类型,值],[描述,类型,值]]],
	//	 ...
	//	]
	function build(dataArray) {
		//info[0] 描述
		//info[1] 类型
		//info[2] 值
		//info[3] TCHAR_ARRAY 大小
		for (var i = 0; i < dataArray.length; i++) {
			var info = dataArray[i];
			if (!!info) {
				switch (info[1]) {
					case "LONG":
						break;
					case "INT":
						writeInt(info[2]);
						break;
					case "DWORD":
						writeDWord(info[2]);
						break;
					case "WORD":
						writeWord(info[2]);
						break;
					case "DWORD[]":
						for (var j = 0; j < info[3]; j++) {
							writeDWord(info[2][j]);
						}
						break;
					case "WORD[]":
						for (var j = 0; j < info[3]; j++) {
							writeWord(info[2][j]);
						}
						break;
					case "DLONG":
						writeDLONG(info[2])
						break;
					case "FLOAT":
						writeFloat(info[2]);
						break;
					case "DOUBLE":
						writeDouble(info[2]);
						break;
					case "BYTE":
						writeByte(info[2]);
						break;
					case "BOOL":
						break;
					case "BOOLEAN":
						writeBoolean(info[2]);
						break;
					case "BYTE[]":
						writeByteArray(info[2], info[3]);
						break;
					case "TCHAR":
						writeCharArray(info[2], info[3]);
						break;
					case "TCHARS":
						writeTCharArray(info[2], info[3]);
						break;
					case "CHINESE":
						writeChineseArray(info[2], info[3])
						break;
					case "CHAR":
						writeChar(info[2]);
						break;
					case "CHARS":
						writeCharArray(info[2], info[3]);
						break;
					case "SCORE":
						break;
					case "LONGLONG":
						break;
					case "LONGLONG[]":
						break;
					case "INT64_NUMBER":
						writeInt64Number(info[2]);
						break;
					case "INT64_BUFFER":
						writeInt64Buffer(info[2]);
						break;
					case "STRUCT":
						build(info[2]);
						break;
					default:
						throw new Error(info[1] + ":undefined "); //使用这种方式报错能够终止后续代码继续运行
				}
			}
		}
	}
}

